﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Engine
{
    /// <summary>
    /// Bond between two points
    /// </summary>
    [Serializable]
    public class Bond
    {
        #region Fields
        
        private int x1;
        
        private int x2;
        
        private int y1;
        
        private int y2;
        
        //for 3-dimensional lattice;
        private int z1;
        
        private int z2;
        
        /** <summary>Start point</summary> */
        private Point _startPoint;

        /** <summary>End point</summary> */
        private Point _endPoint;

        /**<summary>Indicate if we need scan throw this bond.</summary>*/
        private bool _isChecked;
        
        /**<summary>Conductance of this particular bond.</summary>*/
        private double _conductance;
        
        #endregion
        
        /**<summary> Add completely diferent 
         * constructor for binary compability.</summary> */
        public Bond()
        {
            
        }

        [Obsolete("Manually set end and start points. Not compatible with object based lattices.")]
        /**<summary> 2-dimensial bond.</summary>*/
        public Bond(int x1, int y1, int x2, int y2)
        {
            this.x1 = x1;
            this.x2 = x2;
            this.y1 = y1;
            this.y2 = y2;
            //add to distinct 2 and 3 dinesional solutions.
            this.z1 = -1;
            this.z2 = -1;
        }

        [Obsolete("Manually set end and start points. Not compatible with object based lattices.")]
        /** 3-dimensional bond. */
        public Bond(int x1, int y1, int z1, int x2, int y2, int z2)
            : this(x1, y1, x2, y2)
        {
            this.z1 = z1;
            this.z2 = z2;
        }

        /**<summary>Start point of bond.</summary> */
        public Point StartPoint
        {
            get { return _startPoint; }
            set 
            {
                this._startPoint = value;
                value.AddBond(this);
            }
        }

        /**<summary>End point of this bond.</summary> */
        public Point EndPoint
        {
            get { return _endPoint; }
            set 
            { 
                this._endPoint = value;
                value.AddBond(this);
            }
        }

        /**<summary>Indicate if we need go trow this bond.</summary> */
        public bool IsChecked 
        {
            get { return _isChecked; }
            set { this._isChecked = value; }
        }

        /**<summary>Conductance of this bond.</summary>*/
        public double Conductance 
        {
            get { return _conductance;  }
            set { _conductance = value; }
        }

        /**<summary>Remove references from start and end point to this bond. 
         * And remove references start and end point from this bond.</summary> */
        public void DisconnectBond()
        {
            if(_endPoint != null) _endPoint.RemoveBond(this);
            _endPoint = null;
            if(_startPoint != null) _startPoint.RemoveBond(this);
            _startPoint = null;
        }
        
        /**<summary>Called from </summary> */
        internal void RemovePoint(Point point)
        {
            if (_startPoint == point) 
            {
                _startPoint = null;
            }
            else if (_endPoint == point)
            {
                _endPoint = null;
            }
            else 
            {
                throw new ArgumentException("Invalid point that have not any relation to this bond.");
            }
        }
        
        public override string ToString()
        {
            return "[Bond Start=" + this._startPoint + " End=" + this._endPoint + " ]";
        }
    }
}
